package cn.signalpha.modules.auth.granter;

import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.tool.utils.StringUtil;
import cn.signalpha.core.tool.utils.WebUtil;
import cn.signalpha.modules.auth.dto.UserInfo;
import cn.signalpha.modules.auth.provider.ITokenGranter;
import cn.signalpha.modules.auth.provider.TokenParameter;
import cn.signalpha.modules.com.entity.enums.UserSourceEnum;
import cn.signalpha.modules.com.entity.UserOauth;
import cn.signalpha.modules.com.service.UserService;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.service.WxOAuth2Service;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * MobileTokenGranter
 */
@Component
@AllArgsConstructor
public class WeChatTokenGranter implements ITokenGranter {

	public static final String GRANT_TYPE = "wechat";

	private final WxMpService wxService;
	private final UserService userService;

	@Override
	public UserInfo grant(TokenParameter tokenParameter) {
		HttpServletRequest request = WebUtil.getRequest();

		String code = request.getParameter("code");
		String appId = request.getParameter("appId");
		if(StringUtil.isAnyBlank(code, appId)) {
			throw new ServiceException("appId或code不能为空");
		}

		UserOauth userOauth = new UserOauth();
		userOauth.setAppId(appId);
		userOauth.setSource(UserSourceEnum.WECHAT_PUBLIC.getValue());
		try {
			WxOAuth2Service oAuth2Service = wxService.switchoverTo(appId).getOAuth2Service();
			WxOAuth2AccessToken accessToken = oAuth2Service.getAccessToken(code);
			userOauth.setOpenId(accessToken.getOpenId());
			userOauth.setUnionId(accessToken.getUnionId());

			//弹出授权时
			if(WxConsts.OAuth2Scope.SNSAPI_USERINFO.equals(accessToken.getScope())){
				WxOAuth2UserInfo wxUserInfo = oAuth2Service.getUserInfo(accessToken, null);
				userOauth.setOpenId(wxUserInfo.getOpenid());
				userOauth.setUnionId(wxUserInfo.getUnionId());
				userOauth.setNickName(wxUserInfo.getNickname());
				userOauth.setAvatar(wxUserInfo.getHeadImgUrl());
			}
		} catch (WxErrorException e) {
			throw new ServiceException(e.getError().getErrorMsg());
		}

		return userService.userInfo(userOauth);
	}

}
